package cn.com.nxt.txb.fragment;

import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.telecom.Call;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;
import com.netease.nim.uikit.common.ui.dialog.DialogMaker;
import com.netease.nim.uikit.common.util.sys.NetworkUtil;
import com.netease.nimlib.sdk.avchat.AVChatCallback;
import com.netease.nimlib.sdk.avchat.AVChatManager;
import com.netease.nimlib.sdk.avchat.constant.AVChatType;
import com.netease.nimlib.sdk.avchat.model.AVChatChannelInfo;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event;
import org.xutils.view.annotation.ViewInject;
import org.xutils.x;

import java.util.ArrayList;
import java.util.List;

import cn.com.nxt.txb.App;
import cn.com.nxt.txb.EnterMeetingActivity;
import cn.com.nxt.txb.R;
import cn.com.nxt.txb.ResponseStatus;
import cn.com.nxt.txb.TextureVideoActivity;
import cn.com.nxt.txb.VideoCallActivity;
import cn.com.nxt.txb.adapter.CallRecordAdapter;
import cn.com.nxt.txb.avchat.activity.AVChatActivity;
import cn.com.nxt.txb.education.activity.ChatRoomActivity;
import cn.com.nxt.txb.httpdelegate.DialingDelegate;
import cn.com.nxt.txb.httpdelegate.LiveDelegate;
import cn.com.nxt.txb.httpdelegate.MeetingDelegate;
import cn.com.nxt.txb.model.CallRecord;
import cn.com.nxt.txb.util.AppConstant;
import cn.com.nxt.txb.util.AppUtil;
import cn.com.nxt.txb.util.KeyboardUtil;
import cn.com.nxt.txb.util.MyItemDecoration;
import cn.com.nxt.txb.util.OnRecyclerItemClickListener;
import cn.com.nxt.txb.widget.XEditText;

/**
 * Created by xuejinwei on 2016/11/11.
 * Email:xuejinwei@outlook.com
 */
@ContentView(R.layout.fragment_call)
public class CallFragment extends BaseFragment {
    @ViewInject(R.id.et_call)
    private XEditText mCallEt;
    @ViewInject(R.id.keyboardView)
    private KeyboardView keyboardView;
    private KeyboardUtil util;
    @ViewInject(R.id.fab_show_keyboard)
    private FloatingActionButton mShowKeyboardFab;
    private String mPhone;
    private List<CallRecord> mRecords;
    private CallRecordAdapter mAdapter;
    private DialingDelegate dialingDelegate;
    private MeetingDelegate meetingDelegate;
    private LiveDelegate liveDelegate;
    @ViewInject(R.id.rv)
    private RecyclerView rv;
    private final byte GET_CALL_RECORDS = 0x24;
    private final byte IS_MEETING_BEGIN = 0x20;
    private final byte MEETING_IN_AUTH = 0x21;
    private final byte MEETING_IN_CHECK = 0x22;
    private final byte LIVE_ADDRESS = 0x23;
    private final byte LIVE_PUBLISH = 0x24;
    private final byte GET_OTHER_NAME = 0x25;

    public static String name;
    public static String roomid;
    public static String meetingid;
    public static int status;
    public static String data;
    private static final int PERMISSION_REQUEST_CODE = 10;

    public static CallFragment newInstance(String info) {
        Bundle args = new Bundle();
        CallFragment fragment = new CallFragment();
        args.putString("info", info);
        fragment.setArguments(args);
        return fragment;
    }

    @Event({R.id.fab_show_keyboard})
    private void onViewClick(View v) {
        switch (v.getId()) {
            case R.id.fab_show_keyboard:
                mCallEt.setFocusable(true);
                mCallEt.requestFocus();
                //int inputback = mCallEt.getInputType();
                mCallEt.setInputType(InputType.TYPE_NULL);
                if (keyboardView.getVisibility() == View.GONE)
                    keyboardView.setVisibility(View.VISIBLE);
                mShowKeyboardFab.setVisibility(View.GONE);
                break;
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = x.view().inject(this, inflater, container);
        //注册广播
        IntentFilter counterActionFilter = new IntentFilter(AppConstant.CALL_RECORD_RELOAD);
        getActivity().registerReceiver(updateCallRecord, counterActionFilter);
        dialingDelegate = new DialingDelegate(this);
        dialingDelegate.getCallRecord(AppUtil.mUser.getToken(), GET_CALL_RECORDS);
        meetingDelegate = new MeetingDelegate(this);
        liveDelegate = new LiveDelegate(this);
        rv.setLayoutManager(new LinearLayoutManager(getActivity()));
        rv.addItemDecoration(new MyItemDecoration());
        util = new KeyboardUtil(listener, keyboardView, mCallEt);
        mRecords = new ArrayList<>();
        mAdapter = new CallRecordAdapter(getActivity(), mRecords);
        mAdapter.setOnItemClickListener(mOnItemClickListener);
        rv.setAdapter(mAdapter);
        mCallEt.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (!mCallEt.hasFocus()) {
                    // showToast("123" + keyboardView.getVisibility());
                    int inputback = mCallEt.getInputType();
                    mCallEt.setInputType(InputType.TYPE_NULL);
                    util.showKeyboard();
                    mCallEt.setInputType(inputback);
                } else {
                    // mCallEt.setFocusable(true);
                    /// mCallEt.requestFocus();
                    //int inputback = mCallEt.getInputType();
                    mCallEt.setInputType(InputType.TYPE_NULL);
                    if (keyboardView.getVisibility() == View.GONE)
                        keyboardView.setVisibility(View.VISIBLE);
                    //  mCallEt.setInputType(inputback);
                    //  showToast("456" + keyboardView.getVisibility() + View.GONE + View.VISIBLE);
//                    InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(getActivity().INPUT_METHOD_SERVICE);
//                    imm.hideSoftInputFromWindow(mCallEt.getWindowToken(), 0);
                }
                mShowKeyboardFab.setVisibility(View.GONE);
                return false;
            }
        });
        mCallEt.setDrawableRightListener(new XEditText.DrawableRightListener() {

            @Override
            public void onDrawableRightClick(View view) {
                Editable editable = ((EditText) view).getText();
                int start = ((EditText) view).getSelectionStart();
                if (editable != null && editable.length() > 0) {
                    if (start > 0) {
                        editable.delete(start - 1, start);
                    }
                }
            }
        });
        return view;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        getActivity().unregisterReceiver(updateCallRecord);
    }

    private KeyboardView.OnKeyboardActionListener listener = new KeyboardView.OnKeyboardActionListener() {

        @Override
        public void swipeUp() {
        }

        @Override
        public void swipeRight() {
        }

        @Override
        public void swipeLeft() {
        }

        @Override
        public void swipeDown() {
        }

        @Override
        public void onText(CharSequence text) {
        }

        @Override
        public void onRelease(int primaryCode) {
        }

        @Override
        public void onPress(int primaryCode) {
        }

        @Override
        public void onKey(int primaryCode, int[] keyCodes) {
            Editable editable = mCallEt.getText();
            int start = mCallEt.getSelectionStart();
            switch (primaryCode) {
                case Keyboard.KEYCODE_DELETE:
                    if (editable != null && editable.length() > 0) {
                        if (start > 0) {
                            editable.delete(start - 1, start);
                        }
                    }
                    break;
                case Keyboard.KEYCODE_CANCEL:
                    keyboardView.setVisibility(View.GONE);
                    break;
                case -11:
                    //showToast("hidden");
                    util.hiddleKeyboard();
                    mShowKeyboardFab.setVisibility(View.VISIBLE);
                    break;
                case -22:
                    // showToast("call");
                    call();
                    break;
                default:
                    editable.insert(start, Character.toString((char) primaryCode));
                    break;
            }
        }
    };

    private void call() {
        mPhone = mCallEt.getText().toString().trim();
        if (TextUtils.isEmpty(mPhone)) {
            showToast("帐号/会议号不能为空！");
            return;
        }
        if (mPhone.length() == 11 && mPhone.startsWith("1")) {
            if (mPhone.equals(AppUtil.mUser.getPhone())) {
                showToast("不能呼叫自己！");
                return;
            }
            showDialog();
            dialingDelegate.getOtherName(AppUtil.mUser.getToken(),mPhone,GET_OTHER_NAME);
        } else if (mPhone.length() == 12 && mPhone.startsWith("81")) {
            startMeeting(mPhone);
        } else {
            showToast("请输入正确的帐号/会议号！");
        }
    }

    public void startAudioVideoCall(AVChatType avChatType, String account,String name) {
        AVChatActivity.launch(getActivity(), account, avChatType.getValue(), AVChatActivity.FROM_INTERNAL,name);
    }

    @Override
    public void success(String result, byte flag) {
        if (flag == GET_CALL_RECORDS)
            getRecordsSuccess(result);
        else if (flag == IS_MEETING_BEGIN)
            isMeetingBeginSuccess(result);
        else if(flag==LIVE_PUBLISH)
            livePublishSuccess(result);
        else if (flag == MEETING_IN_AUTH)
            meetingInAuthSuccess(result);
        else if (flag == MEETING_IN_CHECK)
            getLiveAddress();
        else if (flag == LIVE_ADDRESS)
            startLive(result);
        else if(flag==GET_OTHER_NAME)
            getOtherNameSuccess(result);
    }

    private void getOtherNameSuccess(String result){
        try {
            JSONObject obj=new JSONObject(result);
            startAudioVideoCall(AVChatType.AUDIO, mPhone,obj.optString("remote_name"));
        } catch (JSONException e) {
        }
    }

    private void livePublishSuccess(String result){
        disDialog();
        data=result;
        meeting();
    }

    @Override
    public void failure(String result, byte flag, ResponseStatus status) {

    }

    @Override
    public void finished(int flag) {

    }

    @Override
    public void cancelled(int flag) {

    }

    private void getRecordsSuccess(String result) {
        try {
            if (mRecords.size() > 0)
                mRecords.clear();
            JSONArray array = new JSONArray(result);
            for (int i = 0; i < array.length(); i++) {
                JSONObject obj = array.getJSONObject(i);
                Gson gson = new Gson();
                CallRecord record = gson.fromJson(obj.toString(), CallRecord.class);
                mRecords.add(record);
            }
            //showToast("长度" + array.length());
            //Log.v("--array--11", "长度" + array.length());
            mAdapter.notifyDataSetChanged();
        } catch (JSONException e) {
        }
    }

    private void startMeeting(String roomId) {
        showDialog("正在检测会议是否开始");
        meetingDelegate.isMeetingBegin(AppUtil.mUser.getToken(), roomId, IS_MEETING_BEGIN);
    }

    private void isMeetingBeginSuccess(String result) {
        try {
            JSONObject obj = new JSONObject(result);
            name = obj.optString("name");
            roomid = obj.optString("roomid");
            meetingid = obj.optString("meetingid");
            status = obj.optInt("status");
            if (status == 1&&roomid.equals(AppUtil.mUser.getRommid())){
                showDialog();
                liveDelegate.livePublish(roomid,LIVE_PUBLISH);
            }else// if (status == 2)
                joinMeeting(roomid);
        } catch (JSONException e) {
        }
    }

    private void meeting() {
        if (!NetworkUtil.isNetAvailable(getActivity())) {
            showToast(R.string.network_is_not_available);
            return;
        }
        if (checkPermission()) {
            createOrEnterRoom();
        } else {
            requestPermissions();
        }
    }

    private void joinMeeting(String roomid) {
        showDialog("正在验证入会权限");
        meetingDelegate.meetingInAuth(AppUtil.mUser.getToken(), roomid, MEETING_IN_AUTH);
    }


    //检查所有的权限
    private boolean checkPermission() {
        final List<String> missed = AVChatManager.checkPermission(getActivity());
        if (missed.size() == 0) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_CODE:
                if (AVChatManager.checkPermission(getActivity()).size() == 0) {
                    createOrEnterRoom();
                } else {
                    showToast("无权限");
                    // Toast.makeText(this, "Some Permission is Denied", Toast.LENGTH_SHORT)
                    //       .show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }

    }

    private void createOrEnterRoom() {
        DialogMaker.showProgressDialog(getActivity(), "", false);
        createChannel(roomid);
    }

    /**
     * 创建会议频道
     */

    private void createChannel(final String roomId) {
        AVChatManager.getInstance().createRoom(roomId, "avchat test", new AVChatCallback<AVChatChannelInfo>() {
            @Override
            public void onSuccess(AVChatChannelInfo avChatChannelInfo) {
                DialogMaker.dismissProgressDialog();
                ChatRoomActivity.start(getActivity(), roomId,meetingid, true, false, data);
                // finish();
            }

            @Override
            public void onFailed(int i) {
                DialogMaker.dismissProgressDialog();
                if (i == 417) {
                    ChatRoomActivity.start(getActivity(), roomid,meetingid, true, false, data);
                    return;
                }
                //关闭视频预览
                //AVChatManager.getInstance().stopVideoPreview();
//离开房间
                AVChatManager.getInstance().leaveRoom2(roomid, new AVChatCallback<Void>() {

                    @Override
                    public void onSuccess(Void aVoid) {

                    }

                    @Override
                    public void onFailed(int i) {

                    }

                    @Override
                    public void onException(Throwable throwable) {

                    }
                });
//关闭音视频引擎
                // AVChatManager.getInstance().disableRtc();
                showToast("创建频道失败, code:" + i);
            }

            @Override
            public void onException(Throwable throwable) {
                DialogMaker.dismissProgressDialog();
            }
        });
    }

    private void requestPermissions() {
        final List<String> missed = AVChatManager.checkPermission(getActivity());
        List<String> showRationale = new ArrayList<>();
        for (String permission : missed) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), permission)) {
                showRationale.add(permission);
            }
        }

        if (showRationale.size() > 0) {
            new AlertDialog.Builder(getActivity())
                    .setMessage("You need to allow some permission")
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ActivityCompat.requestPermissions(getActivity(), missed.toArray(new String[missed.size()]),
                                    PERMISSION_REQUEST_CODE);
                        }
                    })
                    .setNegativeButton("Cancel", null)
                    .create()
                    .show();
        } else {
            ActivityCompat.requestPermissions(getActivity(), missed.toArray(new String[missed.size()]), PERMISSION_REQUEST_CODE);
        }
    }

    private void startLive(String result) {
        Intent intent = new Intent(getActivity(), TextureVideoActivity.class);
        intent.putExtra("roomid", mPhone);
        intent.putExtra("meetingid", meetingid);
        intent.putExtra("path", "rtmp://" + result + ":1935/txb/" + mPhone);
        intent.putExtra("isRecord", true);//是否上报拨号记录
        startActivity(intent);
    }

    private void meetingInAuthSuccess(String result) {
        try {
            JSONObject obj = new JSONObject(result);
            int auth = obj.optInt("auth");
            if (auth == 0)
                checkMeetingPassword();
            else if (auth == 1)
                getLiveAddress();//有权限，直接获取
        } catch (JSONException e) {
        }
    }

    private void checkMeetingPassword() {
        final EditText et = new EditText(getActivity());
        et.setHint("请输入入会密码");
        new AlertDialog.Builder(getActivity()).setTitle("搜索")
                .setIcon(android.R.drawable.ic_dialog_info)
                .setView(et)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        String input = et.getText().toString();
                        showToast("正在验证入会密码");
                        meetingDelegate.meetingInCheck(AppUtil.mUser.getToken(), input, MEETING_IN_CHECK);
                    }
                })
                .setNegativeButton("取消", null)
                .show();
    }

    private void getLiveAddress() {
        showDialog("正在进入房间");
        liveDelegate.liveAddress(LIVE_ADDRESS);
    }

    private OnRecyclerItemClickListener mOnItemClickListener = new OnRecyclerItemClickListener() {
        @Override
        public void OnItemClick(View v, int pos) {
            CallRecord record = mRecords.get(pos);
            if (record.getPhone().startsWith("1")) {
                if (record.getPhone().equals(AppUtil.mUser.getPhone())) {
                    showToast("不能呼叫自己！");
                    return;
                }
                startAudioVideoCall(AVChatType.AUDIO, record.getPhone(),record.getName());
            } else if (record.getPhone().startsWith("81")) {
                startMeeting(record.getPhone());
            }
        }
    };

    private BroadcastReceiver updateCallRecord = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            dialingDelegate.getCallRecord(AppUtil.mUser.getToken(), GET_CALL_RECORDS);
        }

    };
}
